/*
 * Copyright (c) 2023 Cshoo Org. All Rights Reserved.
 */

package org.cshoo.tattoo.authorize.domain.service;

import lombok.extern.slf4j.Slf4j;
import org.cshoo.tattoo.authorize.domain.po.*;
import org.cshoo.tattoo.authorize.domain.repository.IGroupUserRelationRepository;
import org.cshoo.tattoo.authorize.domain.repository.IUserRepository;
import org.cshoo.tattoo.embed.infra.exception.ValidateException;
import org.cshoo.tattoo.embed.infra.utils.AuditFieldsUtils;
import org.cshoo.tattoo.embed.infra.utils.UserUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.List;
import java.util.Optional;

/**
 * @author 杨翼
 * @since 1.0
 */
@Slf4j
@Service
public class UserService {

    public static final String DEFAULT_PASSWORD = "cshoo1234";

    @Resource
    private IUserRepository userRepository;

    @Resource
    private IGroupUserRelationRepository groupUserRelationRepository;

    /**
     * 添加用户，给默认密码为cshoo1234
     *
     * @param user 用户
     */
    public void addUser(User user) {
        user.setPassword(new BCryptPasswordEncoder().encode(DEFAULT_PASSWORD));
        AuditFieldsUtils.setAddAuditFields(user);
        userRepository.save(user);
    }

    /**
     * 修改用户,只修改用户姓名等信息
     *
     * @param user 用户
     */
    public void updateUser(User user) {
        AuditFieldsUtils.setUpdateAuditFields(user);
        userRepository.updateUser(user);
    }

    /**
     * 用户重值密码
     *
     * @param userId 用户id
     */
    public void resetPassword(Long userId) {
        Optional<User> userOptional = userRepository.findById(userId);
        if (userOptional.isPresent()) {
            User user = userOptional.get();
            user.setPassword(new BCryptPasswordEncoder().encode(DEFAULT_PASSWORD));
            AuditFieldsUtils.setUpdateAuditFields(user);
            userRepository.save(user);
        }
    }

    /**
     * 修改密码
     *
     * @param oldPassword 旧密码
     * @param newPassword 新密码
     */
    public void modifyPassword(String oldPassword, String newPassword) throws ValidateException {
        User user = userRepository.findUserByUsername(UserUtils.getUser().getUsername());
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        if (passwordEncoder.matches(oldPassword, user.getPassword())) {
            user.setPassword(passwordEncoder.encode(newPassword));
            AuditFieldsUtils.setUpdateAuditFields(user);
            userRepository.save(user);
        } else {
            throw new ValidateException("old password error");
        }
    }

    /**
     * 查询所有用户，分批
     *
     * @param pageNum  页码
     * @param pageSize 每页条数
     * @return 用户分页查询的信息
     */
    public Page<User> findAllUser(int pageNum, int pageSize) {
        PageRequest pageRequest = PageRequest.of(pageNum, pageSize);
        return userRepository.findAll(pageRequest);
    }

    /**
     * 根据群组id查询用户
     *
     * @param groupId 群组id
     * @return 用户列表
     */
    public List<User> findUsersByGroupId(Long groupId) {
        log.info("groupId:{}", groupId);
        return userRepository.findUsersByGroupId(groupId);
    }

    /**
     * 根据用户名或者用户姓名模糊查询用户
     *
     * @return 用户列表
     */
    public List<User> findUserByName(String name) {
        log.info("name:{}", name);
        return userRepository.findUserByName(name);
    }

    /**
     * 删除用户
     *
     * @param ids id
     */
    public void deleteUsers(List<Long> ids) {
        for (Long id : ids) {
            userRepository.deleteById(id);
        }
    }

    /**
     * 分配一个群组
     *
     * @param userId  用户id
     * @param groupId 群组id
     */
    public void assignGroup(Long userId, Long groupId) {
        GroupUserRelation groupUserRelation = new GroupUserRelation();
        groupUserRelation.setUserId(userId);
        groupUserRelation.setGroupId(groupId);
        AuditFieldsUtils.setAddAuditFields(groupUserRelation);
        groupUserRelationRepository.save(groupUserRelation);
    }

    /**
     * 授予菜单权限
     *
     * @param userId 用户id
     * @param menuId 菜单id
     */
    public void authorizeMenu(Long userId, Long menuId) {
        log.info("userId:{},menuId:{}", userId, menuId);
        userRepository.authorizeMenu(userId, menuId);
    }

    /**
     * 取消菜单权限
     *
     * @param userId 用户id
     * @param menuId 菜单id
     */
    public void cancelMenuAuthority(Long userId, Long menuId) {
        log.info("userId:{},menuId:{}", userId, menuId);
        userRepository.cancelMenuAuthority(userId, menuId);
    }

    /**
     * 授予按钮权限
     *
     * @param userId   用户id
     * @param buttonId 按钮id
     */
    public void authorizeButton(Long userId, Long buttonId) {
        log.info("userId:{},buttonId:{}", userId, buttonId);
        userRepository.authorizeButton(userId, buttonId);
    }
}
